//
//  HMPullDownToRefreshControl.swift
//  48-下拉刷新控件
//
//  Created by Apple on 16/7/25.
//  Copyright © 2016年 Apple. All rights reserved.
//

import UIKit

/// 3中状态的枚举
enum PullDownToRefreshControlStatus {
    case Normal     // 下拉刷新
    case Pulling    // 释放刷新
    case Refreshing // 正在刷新
}

/// 下拉刷新控件
class HMPullDownToRefreshControl: UIView {
    
    private let PullDownToRefreshControlHeight: CGFloat = 60
    
    /// 进入下拉刷新的闭包
    var refreshingCallback: (() -> Void)?
    
    /// 当前状态, 默认为 下拉刷新
    private var currentStatus: PullDownToRefreshControlStatus = .Normal {
        didSet {
            // 判断当前状态
            switch currentStatus {
            case .Normal:
                // 箭头朝下, 文字 下拉刷新
                messageLabel.text = "下拉刷新"
                
                UIView.animateWithDuration(0.25, animations: { () -> Void in
                    self.arrowImageView.transform = CGAffineTransformIdentity
                })
                
            case .Pulling:
                // 文字 释放刷新, 箭头朝上
                messageLabel.text = "释放刷新"
                
                UIView.animateWithDuration(0.25, animations: { () -> Void in
                    self.arrowImageView.transform = CGAffineTransformMakeRotation(CGFloat(M_PI))
                })
                
            case .Refreshing:
                // 箭头隐藏, 风火轮显示, 文字 正在刷新...
                self.arrowImageView.hidden = true
                self.loadingImageView.hidden = false
                messageLabel.text = "正在刷新..."
                
                // 风火轮动画
                let anim = CABasicAnimation(keyPath: "transform.rotation")
                anim.toValue = 2 * M_PI
                anim.duration = 0.75
                anim.repeatCount = MAXFLOAT
                // 切换到其他界面再切回来才不会停下来
                anim.removedOnCompletion = false
                
                // 添加到图片上面
                // key: 给动画去名称,下次添加一个名称一样的动画,会先停掉上次的,在重新开始
                loadingImageView.layer.addAnimation(anim, forKey: "anim")
                
                // 整个刷新控件显示出来,让tableView的内容往下走
                // contentInset可以改变tableView内容的起始位置
//                self.newSuperScrollView?.contentOffset = CGPoint(x: 0, y: -124)
                // 在当前的 contentInset 基础上往下移动 刷新控件的高度
                UIView.animateWithDuration(0.25, animations: { () -> Void in
                    self.newSuperScrollView?.contentInset.top = self.newSuperScrollView!.contentInset.top + self.PullDownToRefreshControlHeight
                })
                
                // 告诉别人进入了刷新状态,让别人去加载数据
                self.refreshingCallback?()
            }
        }
    }
    
    /// 父控件
    var newSuperScrollView: UIScrollView?
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    /// 外面调用没有参数的构造函数init(),最终都会走到init(frame)
    override init(frame: CGRect) {
        
        // 不要别人传进来的frame,我们自己来创建frame
        let newFrame = CGRect(x: 0, y: -PullDownToRefreshControlHeight, width: UIScreen.mainScreen().bounds.size.width, height: 60)
        
        super.init(frame: newFrame)
        
        setupUI()
    }
    
    // MARK: - 公开的方法
    // 直接进入刷新状态
    func beginRefreshing() {
        self.currentStatus = .Refreshing
    }
    
    /// 结束刷新
    func endRefreshing() {
        // 从正在刷新 切换状态到 Normal
        if self.currentStatus == .Refreshing {
            self.currentStatus = .Normal
            
            // 从正在刷新状态会来
            // 结束风火轮旋转, 箭头显示出来
            self.loadingImageView.layer.removeAllAnimations()
            self.loadingImageView.hidden = true
            self.arrowImageView.hidden = false
            // 刷新控件回去不要看到
            UIView.animateWithDuration(0.25, animations: { () -> Void in
                self.newSuperScrollView?.contentInset.top = self.newSuperScrollView!.contentInset.top - self.PullDownToRefreshControlHeight
            })
        }
    }
    
    private func setupUI() {
        // 隐藏风火轮
        self.loadingImageView.hidden = true
        
        // 添加子控件
        self.addSubview(loadingImageView)
        self.addSubview(arrowImageView)
        self.addSubview(messageLabel)
        
        // 添加约束
        loadingImageView.translatesAutoresizingMaskIntoConstraints = false
        arrowImageView.translatesAutoresizingMaskIntoConstraints = false
        messageLabel.translatesAutoresizingMaskIntoConstraints = false
        
        /// 这个框架写好是给别人用的,尽量少依赖其他东西
        /// 箭头
        // 箭头右边父控件中心 左偏移 25
        self.addConstraint(NSLayoutConstraint(item: arrowImageView, attribute: NSLayoutAttribute.Trailing, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: -25))
        
        self.addConstraint(NSLayoutConstraint(item: arrowImageView, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0))
        
        // 风火轮center和箭头重合
        self.addConstraint(NSLayoutConstraint(item: loadingImageView, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: arrowImageView, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0))
        self.addConstraint(NSLayoutConstraint(item: loadingImageView, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: arrowImageView, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0))
        
        // 文字
        self.addConstraint(NSLayoutConstraint(item: messageLabel, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: arrowImageView, attribute: NSLayoutAttribute.Trailing, multiplier: 1, constant: 30))
        self.addConstraint(NSLayoutConstraint(item: messageLabel, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: self, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0))
    }

    /// 即将移动到父控件中, 调用addSubview后触发的
    override func willMoveToSuperview(newSuperview: UIView?) {
//        print("newSuperview \(newSuperview)")
        
        // 可以获取到下拉刷新的父控件
        // 判断父控件是否是scrollView
        if newSuperview is UIScrollView {
            // 父控件可以滚动, 监听父控件的滚动
            self.newSuperScrollView = newSuperview as? UIScrollView
            
            // KVO: key value observer: 键值监听, 监听某个对象的某个属性值的改变
            // 通知: 一个人发送通知,一个人接收通知, 键盘弹出, textView文字改变
            // 使用KVO监听滚动
            // "buttonClick:"
            // 要监听谁的属性,就用谁调用: addObserver:forKeyPath:options:context:
            // observer: 观察者,谁来监听
            // forKeyPath: 要监听的属性
            self.newSuperScrollView?.addObserver(self, forKeyPath: "contentOffset", options: NSKeyValueObservingOptions(rawValue: 0), context: nil)
        }
    }
    
    /// KVO一定要记得移除
    deinit {
        // 注意: KVO移除,用被监听的那个对象来移除
        self.newSuperScrollView?.removeObserver(self, forKeyPath: "contentOffset")
    }
    
    /// 实现KVO方法
    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
        // contentOffset改变了
//        print("contentOffset: \( self.newSuperScrollView!.contentOffset)")
        // 下拉刷新和释放刷新切换,用户手要一直拖动
        // 释放刷新到正在刷新,用户松手的时候判断
        if self.newSuperScrollView!.dragging {
            // 用户手拖动
            // 状态重复切换问题
            // 下拉刷新 <==> 释放刷新
            if self.currentStatus == .Pulling && self.newSuperScrollView?.contentOffset.y > -124 {   // -80 > -124, 下拉刷新控件没有完全显示
                // Normal状态(下拉刷新)
//                print("切换状态到Normal")
                self.currentStatus = .Normal
                
            } else if self.currentStatus == .Normal && self.newSuperScrollView?.contentOffset.y <= -124 {    // -140 < -124, 下拉刷新控件完全显示
                // Pulling状态(释放刷新)
//                print("切换状态到Pulling")
                self.currentStatus = .Pulling
            }
            
        } else {
            // 用户松手了, 释放刷新 ==> 正在刷新
            if self.currentStatus == .Pulling {
                self.currentStatus = .Refreshing
//                print("切换状态到Refreshing")
            }
        }
    }
    
    // MARK: - 懒加载
    /// 箭头
    private lazy var arrowImageView: UIImageView = UIImageView(image: UIImage(named: "tableview_pull_refresh"))
    
    /// 风火轮
    private lazy var loadingImageView: UIImageView = UIImageView(image: UIImage(named: "tableview_loading"))
    
    /// 文字
    private lazy var messageLabel: UILabel = {
        let label = UILabel()
        
        // 设置内容
        label.text = "下拉刷新"
        label.font = UIFont.systemFontOfSize(15)
        label.textColor = UIColor.darkGrayColor()
        
        return label
    }()
}
